package com.forestar.xzk.commonview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.Scroller;

import androidx.annotation.Nullable;

import com.forestar.xzk.logs.LogTag;
import com.forestar.xzk.threadFor.ThreadUtils;

/**
 * created by  xzk
 * 2020/7/6   9:37
 * 说明: view支持滚动
 */
public class MoveView extends View implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener
        , ScaleGestureDetector.OnScaleGestureListener {

    private GestureDetector gestureDetector;
    private Scroller scroller;

//    private int[] lines = new int[24];
    private Paint paint;


    public MoveView(Context context) {
        this(context,null);
    }

    public MoveView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MoveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initData();
        init();
    }

    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {

    }

    private void initData(){
    }
    private ScaleGestureDetector scaleGestureDetector ;

    private void init(){
        gestureDetector = new GestureDetector(this);
        gestureDetector.setOnDoubleTapListener(this);
        scroller = new Scroller(getContext());
        scaleGestureDetector= new  ScaleGestureDetector(getContext(),this);
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(3);
        paint.setStrokeCap(Paint.Cap.ROUND);
    }

    private PointF center=new PointF(100,100);
    private float widthView = 100;
    private float heightView = 100;

    private RectF rectDraw = new RectF(center.x-50,center.y-50,center.x+50,center.y+50);

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float vWidth = widthView * currentScale / 2;
        float vHeight = heightView * currentScale / 2;
        float left = center.x-vWidth;
        float right = center.x+vWidth;
        float top = center.y-vHeight;
        float bottom = center.y+vHeight;
        rectDraw.set(left,top,right,bottom);
        Log.d("绘制位置","==>"+rectDraw.toString());
        canvas.drawRect(rectDraw,paint);
    }

    private boolean isScaleEvent = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int pointerCount = event.getPointerCount(); // 获得多少点
        if (pointerCount > 1) {// 多点触控，
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isScaleEvent=true;
                    break;
                case MotionEvent.ACTION_MOVE:

                    break;
                case MotionEvent.ACTION_POINTER_2_UP://第二个手指抬起的时候
                    isScaleEvent=true;
                    break;

                default:
                    break;
            }
            return scaleGestureDetector.onTouchEvent(event);//让mScaleGestureDetector处理触摸事件
        } else {
//             if(gestureDetector.onTouchEvent(event)){
//                 return true;
//             }
        }
//        LogTag.d("触摸事件："+event.getAction());
//        if(!isScaleEvent){
//            if(gestureDetector.onTouchEvent(event) && !isScaleEvent){
//                return true;
//            }
//        }
//        if(scaleGestureDetector.onTouchEvent(event)){
//            return true;
//        }
//        Log.d(TAG,"此手势未被处理:"+event.getAction());
//        if(event.getAction() == MotionEvent.ACTION_MOVE && isScaleEvent){
//            // LogTag.d("双指移动，处理缩放");
//            int pointerCount = event.getPointerCount();
//            if(pointerCount>1){
//                scaleSum(event);
//                return true;
//            }
//        }
//        //双指触摸
//        if(event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN) {
////            LogTag.d("双指触摸开始");
//            isScaleEvent =true;
//            return true;
//        }
//        if(event.getAction() == MotionEvent.ACTION_POINTER_2_UP) {
//            isScaleEvent =false;
////            LogTag.d("双指触摸抬起，初始化");
//            scaleDistance = null;
//            scaleDistanceNow = null;
//            return true;
//        }
        return super.onTouchEvent(event);
    }

    //    缩放相关参数
    private float normalScale = 1f;
    private float currentScale = 1f;
    private float minScale = 0.1f;
    private float maxScale = 100f;

    private Float scaleDistance = null;
    private Float scaleDistanceNow = null;
    /**
     * 按照双指移动距离，计算放大，或者缩小
     * 按下时记录，抬起时清除记录
     * 记录第二指的触点，  计算两点间的距离，   每次触发，计算距离 ，   然后距离和首次存储的距离做除法，计算缩放比例，并更新当前的缩放比
     *
     * 根据当前最大缩放比和最小缩放比，确定临界值
     *
     */
    private void scaleSum(MotionEvent event){
        if(null == scaleDistance){
            scaleDistance= distance(event);
        }
        scaleDistanceNow= distance(event);

        float v = scaleDistanceNow/scaleDistance ;
        LogTag.d("目前缩放比:"+scaleDistanceNow+"<====>"+scaleDistance+"<====>"+v);
      getScaleSize(v);
      //开始绘制图像
      postInvalidate();
    }
    private float getScaleSize(float value){
        normalScale = value;
        if(normalScale > maxScale){
            normalScale = maxScale;
        }
        if(normalScale < minScale){
            normalScale = minScale;
        }
        return normalScale;
    }
    //计算两指间的距离
    private float distance(MotionEvent event) {
        float dx = event.getX(1) - event.getX(0);
        float dy = event.getY(1) - event.getY(0);
        LogTag.d("目前缩放比2:"+event.getX(1)+"<====>"+event.getX(0)+"<====>" );
        LogTag.d("目前缩放比2:"+event.getY(1)+"<====>"+event.getY(0)+"<====>" );
        LogTag.d("目前缩放比2:"+dx+"<====>"+dy+"<====>" );
        float vDX =Math.abs(dx * dx) ;
        float vDY = Math.abs(dy * dy);
        return Float.parseFloat(Math.sqrt(vDX + vDY)+"");

//        return (float) Math.sqrt(dx * dx + dy * dy);
    }

    @Override
    public boolean onDown(MotionEvent motionEvent) {
//        Log.d("手势事件","按下："+motionEvent.getX()+"<--->"+motionEvent.getY());
        //这里必须为true，否则，点击事件就不在这里面
//        if(!scroller.isFinished()){
//            scroller.abortAnimation();
//        }
//        Log.d(TAG,"点击手势:"+motionEvent.getAction());
//        MotionEvent.ACTION_POINTER_DOWN
        if (mIsFlinging) {
            if (scroller!=null)	//fix for edit mode in the IDE
                scroller.abortAnimation();
            mIsFlinging = false;
        }
        //
        scrollTo( (int)motionEvent.getX() ,(int)motionEvent.getY());
//        center.set(motionEvent.getX(),motionEvent.getY());
//        postInvalidate();
        return true;
    }

    @Override
    public void scrollTo(int x, int y) {
        Log.d("目标点","位置x==>"+x+"-->"+y);
        center.set(x,y);
//        super.scrollTo(x, y);
//        ThreadUtils
        postInvalidate();
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {
//        Log.d("手势事件","onShowPress点击："+motionEvent.getX()+"<--->"+motionEvent.getY());
    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
//        Log.d("手势事件","点击："+motionEvent.getX()+"<--->"+motionEvent.getY());
        return true;
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float distanceX, float distanceY) {
//        Log.d("手势事件","滚动1："+motionEvent.getX()+"<--->"+motionEvent.getY());//表示的是滚动起始位置
//        Log.d("手势事件","滚动2："+motionEvent1.getX()+"<--->"+motionEvent1.getY());//当前滚动到的位置
//        Log.d("手势事件","滚动3："+distanceX+"<--->"+distanceY);
        scrollTo((int) motionEvent1.getX(), (int)  motionEvent1.getY());
//        scrollBy((int) distanceX, (int) distanceY);
        return true;
    }

    @Override
    public void scrollBy(int distanceX, int distanceY) {
        scrollTo(((int)center.x) + distanceX, ((int)center.y)  + distanceY);
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {
//        Log.d("手势事件","长按点击："+motionEvent.getX()+"<--->"+motionEvent.getY());

    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float velocityX, float velocityY) {
        Log.d("手势事件","扔1："+motionEvent.getX()+"<--->"+motionEvent.getY());
        Log.d("手势事件","扔2："+motionEvent1.getX()+"<--->"+motionEvent1.getY());
        Log.d("手势事件","扔3："+velocityX+"<--->"+velocityY);
        mIsFlinging = true;
//        Point v = new Point((int)velocityX, (int)velocityY);
        scroller.fling((int) motionEvent.getX(), (int) motionEvent.getY(), ((int)velocityX), ((int)velocityY),
                Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
        return true;
    }

    private static final String TAG = "手势事件";
    private boolean mIsFlinging = false;

    @Override
    public void computeScroll() {
        super.computeScroll();
        Log.d(TAG,"滑动效果:"+scroller.getCurrX()+"---"+scroller.getCurrY());
        Log.d(TAG,"滑动效果:"+scroller.getStartX()+"---"+scroller.getStartY());
        Log.d(TAG,"滑动效果:"+scroller.getFinalX()+"---"+scroller.getFinalY());
//        Log.d(TAG,"必须要使用这个才能连续滑动:"+(!scroller.isFinished()));
//        Log.d(TAG,"必须要使用这个才能连续时间滑动:"+(scroller.getDuration()));
        if (scroller == null) { //fix for edit mode in the IDE
            return;
        }
        if (!mIsFlinging) {
            return;
        }
        if (!scroller.computeScrollOffset()) {
            return;
        }
        //使用这个判断才能达到惯性滑动的效果
        if (scroller.isFinished()) {
            // we deliberately ignore the very last scrollTo, which sometimes provokes map hiccups
            mIsFlinging = false;
        } else {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            //必须要使用这个才能连续滑动
//            postInvalidate();
        }
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
//        Log.d("手势事件","onSingleTapConfirmed按下--单击手势确定："+motionEvent.getX()+"<--->"+motionEvent.getY());
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent motionEvent) {
//        Log.d("手势事件","onDoubleTap 按下："+motionEvent.getX()+"<--->"+motionEvent.getY());
        return false;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent motionEvent) {
//        Log.d("手势事件","onDoubleTapEvent 按下："+motionEvent.getX()+"<--->"+motionEvent.getY());
        return false;
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        float previousSpan = detector.getPreviousSpan();// 前一次双指间距
        float currentSpan = detector.getCurrentSpan();// 本次双指间距
        Log.d("手势事件","onScale1："+currentSpan+"<--->"+previousSpan);
        if (currentSpan < previousSpan) {
            // 缩小
            currentScale = normalScale - (previousSpan - currentSpan) / 1000;
        } else {
            // 放大
            currentScale = normalScale + (currentSpan - previousSpan) / 1000;
        }

//        LogTag.d("缩放比:"+detector.getScaleFactor());
//        if(detector.getScaleFactor()<1){
//            //收缩一次
//            currentScale = currentScale-zoomInterval;
//        }else if(detector.getScaleFactor()>1){
//            //扩大一次
//            currentScale = currentScale+zoomInterval;
//        }else {
//            return true;
//        }
//        currentScale = normalScale * detector.getScaleFactor();
        if(currentScale > maxScale){
            currentScale = maxScale;
        }
        if(currentScale < minScale){
            currentScale = minScale;
        }
        Log.d("手势事件","onScale1缩放数据："+currentScale+"<--->");
        postInvalidate();
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        LogTag.d("缩放比onScaleBegin:"+detector.getScaleFactor());
        normalScale = currentScale;
        isScaleEvent = true;
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        LogTag.d("缩放比onScaleEnd:"+detector.getScaleFactor());
        isScaleEvent = false;
    }
}
